import CodeView from "../../../shared/components/CodeView";
import CodeBlock from "../../../shared/components/CodeBlock";
import Blockquote from "../../../shared/components/Blockquote";
import DisplayColumn from "../../../shared/components/DisplayColumn";
import DisplayGrid from "../../../shared/components/DisplayGrid";
import * as PopoverExamples from "./base/example";
import * as BrandExamples from "./brand/example";
import * as NubbinExamples from "./nubbins/example";
import * as ErrorExamples from "./error/example";
import * as WarningExamples from "./warning/example";
import * as WalkthroughExamples from "./walkthrough/example";
import * as FeatureExamples from "./feature/example";
import * as PreviewPanelExamples from "./panels/example";
import * as PromptExamples from "./prompt/example";
import { getDisplayElementById } from "../../shared/helpers";
import StylingHooksTable from "../../../shared/components/StylingHooksTable";

<div className="doc lead">
  A popover is a non-modal dialog. The component should be paired with a
  clickable trigger element and contain at least one focusable element.
</div>

<CodeView exampleOnly>
  {getDisplayElementById(NubbinExamples.states, "bottom")}
</CodeView>

## About Popovers

A popover is used to display contextual information to the user.

A popover can accept the following nubbin position classes, `.slds-nubbin_left`, `.slds-nubbin_left-top`, `.slds-nubbin_left-bottom`, `.slds-nubbin_top-left`, `.slds-nubbin_top-right`, `.slds-nubbin_right-top`, `.slds-nubbin_right-bottom`, `.slds-nubbin_bottom-left`, `.slds-nubbin_bottom-right`.

### Accessibility

#### Notable features

- Popovers **must** come with a triggering button
- They **must** have at least one focusable element inside
- They **should** be implemented as a keyboard focus trap
- When triggered, user focus should be placed on the first focusable element that isn't the close button. If the close button is the only focusable element, focus should be placed there
- Pressing the Escape the key as well as clicking the close button should close the Popover
- User focus should be placed back on the triggering button when the popover is closed

Panel Popovers can be shown on mouse hover but for keyboard or screen reader users, a button should be present **in addition** and next to the hover trigger. This is due to the focus moving and trapping nature of non-modal dialogs. You **should not** move a user's focus without their expressed intent.

#### Notable attributes

- The Popover element should have `role="dialog"` applied
- The `dialog` should be labelled, this can be achieved in two ways:
  - Apply the `aria-labelledby` attribute to the `dialog` element and set the value to be the ID of the main Heading element in the Popover (if it provides a good and meaningful title to the `dialog`)
  - If no Heading element is present, use the `aria-label` attribute and set the value to be a meaningful title of the `dialog`
- The `dialog` should be described where possible. This can be achieved by applying the `aria-describedby` attribute to the `dialog` element and set the value to be the id of the Popover body
- The triggering element **must** have `aria-haspopup="true"` when the popover is opened and `aria-haspopup="false"` when the popover is closed

## Base

<CodeView>{getDisplayElementById(PopoverExamples.default)}</CodeView>

### With Header

<CodeView>{getDisplayElementById(PopoverExamples.examples, "header")}</CodeView>

### With Footer

<CodeView>{getDisplayElementById(PopoverExamples.examples, "footer")}</CodeView>

### With Badge

<CodeView>{getDisplayElementById(PopoverExamples.examples, "badge")}</CodeView>

### Scrolling region with max-height

<CodeView>
  {getDisplayElementById(PopoverExamples.examples, "scrolling")}
</CodeView>

## Widths

### Small

<CodeView>
  {getDisplayElementById(PopoverExamples.examples, "width-small")}
</CodeView>

### Medium

<CodeView>
  {getDisplayElementById(PopoverExamples.examples, "width-medium")}
</CodeView>

### Large

<CodeView>
  {getDisplayElementById(PopoverExamples.examples, "width-large")}
</CodeView>

### Full Width

<CodeView>
  {getDisplayElementById(PopoverExamples.examples, "width-full-width")}
</CodeView>

## Nubbins

### Left

<DisplayGrid>
  <DisplayColumn>
    <strong>Left</strong>
    <CodeView>{getDisplayElementById(NubbinExamples.states, "left")}</CodeView>
  </DisplayColumn>
  <DisplayColumn>
    <strong>Left Top</strong>
    <CodeView>
      {getDisplayElementById(NubbinExamples.states, "left-top")}
    </CodeView>
  </DisplayColumn>
  <DisplayColumn columnCount="1">
    <strong>Left Bottom</strong>
    <CodeView>
      {getDisplayElementById(NubbinExamples.states, "left-bottom")}
    </CodeView>
  </DisplayColumn>
</DisplayGrid>

### Right
<DisplayGrid>
  <DisplayColumn>
    <strong>Right</strong>
    <CodeView>{getDisplayElementById(NubbinExamples.states, "right")}</CodeView>
  </DisplayColumn>
  <DisplayColumn>
    <strong>Right Top</strong>
    <CodeView>
      {getDisplayElementById(NubbinExamples.states, "right-top")}
    </CodeView>
  </DisplayColumn>
  <DisplayColumn columnCount="1">
    <strong>Right Bottom</strong>
    <CodeView>
      {getDisplayElementById(NubbinExamples.states, "right-bottom")}
    </CodeView>
  </DisplayColumn>
</DisplayGrid>

### Top
<DisplayGrid>
  <DisplayColumn>
    <strong>Top</strong>
    <CodeView>{getDisplayElementById(NubbinExamples.states, "top")}</CodeView>
  </DisplayColumn>
  <DisplayColumn>
    <strong>Top Left</strong>
    <CodeView>
      {getDisplayElementById(NubbinExamples.states, "top-left")}
    </CodeView>
  </DisplayColumn>
  <DisplayColumn columnCount="1">
    <strong>Top Right</strong>
    <CodeView>
      {getDisplayElementById(NubbinExamples.states, "top-right")}
    </CodeView>
  </DisplayColumn>
</DisplayGrid>

### Bottom
<DisplayGrid>
  <DisplayColumn>
    <strong>Bottom</strong>
    <CodeView>
      {getDisplayElementById(NubbinExamples.states, "bottom")}
    </CodeView>
  </DisplayColumn>
  <DisplayColumn>
    <strong>Bottom Left</strong>
    <CodeView>
      {getDisplayElementById(NubbinExamples.states, "bottom-left")}
    </CodeView>
  </DisplayColumn>
  <DisplayColumn columnCount="1">
    <strong>Bottom Right</strong>
    <CodeView>
      {getDisplayElementById(NubbinExamples.states, "bottom-right")}
    </CodeView>
  </DisplayColumn>
</DisplayGrid>

## Feedback States

### Error

<CodeView>{getDisplayElementById(ErrorExamples.default)}</CodeView>

#### With Footer

<CodeView>
  {getDisplayElementById(ErrorExamples.examples, "with-footer")}
</CodeView>

#### With Bullet List

<CodeView>
  {getDisplayElementById(ErrorExamples.examples, "with-bullet-list")}
</CodeView>

### Warning

<CodeView>{getDisplayElementById(WarningExamples.default)}</CodeView>

#### With Footer

<CodeView>
  {getDisplayElementById(WarningExamples.examples, "with-footer")}
</CodeView>

## Examples

### Walkthrough

<CodeView>{getDisplayElementById(WalkthroughExamples.default)}</CodeView>

#### Micro Setup

<CodeView>
  {getDisplayElementById(WalkthroughExamples.examples, "micro-setup-dark")}
</CodeView>

#### Micro Setup - Alternate

<CodeView>
  {getDisplayElementById(WalkthroughExamples.examples, "micro-setup-alternate-dark")}
</CodeView>

#### Micro Setup - In Page

<CodeView>
  {getDisplayElementById(WalkthroughExamples.examples, "micro-setup-in-page-dark")}
</CodeView>

#### Micro Setup - Inline Form

<CodeView>
  {getDisplayElementById(
    WalkthroughExamples.examples,
    "micro-setup-inline-form-dark"
  )}
</CodeView>

#### Action

<CodeView>
  {getDisplayElementById(WalkthroughExamples.examples, "action-popover-dark")}
</CodeView>

#### Action - With Heading

<CodeView>
  {getDisplayElementById(
    WalkthroughExamples.examples,
    "action-popover-heading-dark"
  )}
</CodeView>

#### Action - With Link

<CodeView>
  {getDisplayElementById(
    WalkthroughExamples.examples,
    "action-popover-with-link-dark"
  )}
</CodeView>

### Feature

<CodeView>{getDisplayElementById(FeatureExamples.default)}</CodeView>

#### With icon and text

<CodeView>
  {getDisplayElementById(FeatureExamples.examples, "icon-text-dark")}
</CodeView>

#### With icon, header, and text

<CodeView>
  {getDisplayElementById(FeatureExamples.examples, "icon-header-text-dark")}
</CodeView>

#### With icon, header, text and link

<CodeView>
  {getDisplayElementById(FeatureExamples.examples, "icon-header-text-link-dark")}
</CodeView>

#### With icon, header, text and footer

<CodeView>
  {getDisplayElementById(FeatureExamples.examples, "icon-header-text-footer-dark")}
</CodeView>

### Record Preview Panel

<CodeView>{getDisplayElementById(PreviewPanelExamples.default)}</CodeView>

### Prompt

<CodeView>{getDisplayElementById(PromptExamples.default)}</CodeView>

#### Positioned top left

<CodeView demoStyles="height: 250px;">
  {getDisplayElementById(PromptExamples.examples, "top-left")}
</CodeView>

#### Positioned top center

<CodeView demoStyles="height: 250px;">
  {getDisplayElementById(PromptExamples.examples, "top-center")}
</CodeView>

#### Positioned top right

<CodeView demoStyles="height: 250px;">
  {getDisplayElementById(PromptExamples.examples, "top-right")}
</CodeView>

#### Positioned bottom right

<CodeView demoStyles="height: 250px;">
  {getDisplayElementById(PromptExamples.examples, "bottom-right")}
</CodeView>

#### Positioned bottom center

<CodeView demoStyles="height: 250px;">
  {getDisplayElementById(PromptExamples.examples, "bottom-center")}
</CodeView>

#### Positioned bottom left

<CodeView demoStyles="height: 250px;">
  {getDisplayElementById(PromptExamples.examples, "bottom-left")}
</CodeView>

#### With brand color and footer

<CodeView demoStyles="height: 250px;">
  {getDisplayElementById(PromptExamples.examples, "brand-with-footer")}
</CodeView>

#### With brand color - no footer

<CodeView demoStyles="height: 250px;">
  {getDisplayElementById(PromptExamples.examples, "brand-without-footer")}
</CodeView>

## Styling Hooks Overview

<Blockquote header="A Note About z-index">
  <p>By default, Popovers use the <code>$z-index-dialog</code> (<a href="/design-tokens/#category-z-index">value of 6000</a>) token. This allows the Popover to appear above the element that triggered it, and in the vast majority of cases should work well out of the box. However, depending on where the Popover code lives when it's triggered, layout issues could arise.</p>

  <p>For this particular use case, the <code>--slds-c-popover-position-zindex</code> <a href="/platforms/lightning/styling-hooks/">Styling Hook</a> allows developers to change the z-index value. <strong>Please note</strong>: when this value is changed, the responsibility is on the developer to maintain the CSS stacking order.</p>

</Blockquote>

<StylingHooksTable name="popovers" type="component" />
